﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Apps;
using VAdvantage.Logging;
using VAdvantage.Utility;
using System.ComponentModel;
using VAdvantage.Controls;
using VAdvantage.DataBase;
using VAdvantage.Classes;
using System.Text;
using System.IO;
using System.Threading;

namespace VAdvantage.Apps.AForms
{
    public partial class ArchiveViewer : UserControl, FormPanel
    {
        public ArchiveViewer()
        {
            InitializeComponent();
            LayoutRoot.Background = new SolidColorBrush(GlobalVariable.WINDOW_BACK_COLOR);
            // grid2.Background = new SolidColorBrush(GlobalVariable.USERCONTROL_BACK_COLOR);
            // DynInit();
            grid1.RowDefinitions[2].Height = new GridLength(0, GridUnitType.Pixel);
        }


        private VAdvantage.Report.IReportLoader c1ReportViewer1 = null;

        /**	Window No			*/
        private int m_WindowNo = 0;
        /**	FormFrame			*/
        private FormFrame m_frame;
        /**	The Archives		*/
        private MArchive[] m_archives = new MArchive[0];
        /** Archive Index		*/
        private int m_index = 0;
        /** Table direct		*/
        private int m_AD_Table_ID = 0;
        /** Record direct		*/
        private int m_Record_ID = 0;

        /**	Logger			*/
        private static VLogger log = VLogger.GetVLogger(typeof(ArchiveViewer).FullName);

        VAdvantage.Controls.VTextBoxButton bPartnerField = null;

        private VComboBox processField = null;

        private VComboBox tableField = null;

        private VComboBox createdByQField = null;

        private void DynInit()
        {
            PageStatus.IsBusy = true;
            int AD_Role_ID = Envs.GetCtx().GetAD_Role_ID();

            KeyNamePair[] namepairProcess = null;
            KeyNamePair[] namepairTables = null;
            KeyNamePair[] namepairUsers = null;
            Lookup lookup = null;

            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += (ov, ev) =>
            {
                //	Processes
                String sql = "SELECT DISTINCT p.AD_Process_ID, p.Name "
                    + "FROM AD_Process p INNER JOIN AD_Process_Access pa ON (p.AD_Process_ID=pa.AD_Process_ID) "
                    + "WHERE pa.AD_Role_ID=" + AD_Role_ID
                    + " AND p.IsReport='Y' AND p.IsActive='Y' AND pa.IsActive='Y' "
                    + "ORDER BY 2";

                namepairProcess = DB.GetKeyNamePairs(sql, true);

                //	Tables
                sql = "SELECT DISTINCT t.AD_Table_ID, t.Name "
                    + "FROM AD_Table t INNER JOIN AD_Tab tab ON (tab.AD_Table_ID=t.AD_Table_ID)"
                    + " INNER JOIN AD_Window_Access wa ON (tab.AD_Window_ID=wa.AD_Window_ID) "
                    + "WHERE wa.AD_Role_ID=" + AD_Role_ID
                    + " AND t.IsActive='Y' AND tab.IsActive='Y' "
                    + "ORDER BY 2";

                namepairTables = DB.GetKeyNamePairs(sql, true);


                //	Internal Users
                sql = "SELECT AD_User_ID, Name "
                    + "FROM AD_User u WHERE EXISTS "
                        + "(SELECT * FROM AD_User_Roles ur WHERE u.AD_User_ID=ur.AD_User_ID) "
                    + "ORDER BY 2";

                namepairUsers = DB.GetKeyNamePairs(sql, true);

                lookup = MLookupFactory.Get(Envs.GetContext(), m_WindowNo, 0, DisplayType.Search, "C_BPartner_ID", 0, false, "");
            };

            bgw.RunWorkerCompleted += (ov, ev) =>
            {
                processField = new VComboBox(namepairProcess);
                tableField = new VComboBox(namepairTables);
                createdByQField = new VComboBox(namepairUsers);

                AddControlToGrid(processField, 2, 1);
                AddControlToGrid(tableField, 3, 1);
                AddControlToGrid(createdByQField, 7, 1);

                bPartnerField = new VAdvantage.Controls.VTextBoxButton("C_BPartner_ID", false, false, true, DisplayType.Search, lookup);
                AddControlToGrid(bPartnerField, 1, 1);

                if (m_AD_Table_ID > 0)
                {
                    reportField.IsChecked = true;
                    Cmd_Query();
                }
                else
                {
                    PageStatus.IsBusy = false;
                }
            };

            bgw.RunWorkerAsync();
        }

        void AddControlToGrid(FrameworkElement element, int row, int col)
        {
            element.Height = 25;
            Grid.SetRow(element, row);
            Grid.SetColumn(element, col);
            element.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            element.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
            grid1.Children.Add(element);
        }

        public void Init(int windowNo, FormFrame frame)
        {

            log.Info("");
            m_WindowNo = windowNo;
            m_frame = frame;
            this.Visibility = System.Windows.Visibility.Visible;
            try
            {
                //m_frame.FormState = SilverlightDesktop.Common.FormState.Maximized;
                //reportField.IsChecked = frame.GetIsReport();
                m_frame.MinWidth = 900;
                m_frame.MinHeight = 500;
                m_frame.ContentGrid.Children.Add(this);

                Type type = Envs.GetC1ModuleType("VC1Module.UI.VC1Viewer");

                if (type != null)
                {
                    c1ReportViewer1 = (VAdvantage.Report.IReportLoader)Activator.CreateInstance(type);
                    container.Child = c1ReportViewer1 as UIElement;
                }

            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "init", e);
            }





            DynInit();

            reportField.Content = Msg.Translate(Envs.GetCtx(), "IsReport");
            processLabel.Text = Msg.Translate(Envs.GetCtx(), "AD_Process_ID");
            tableLabel.Text = Msg.Translate(Envs.GetCtx(), "AD_Table_ID");
            bPartnerLabel.Text = Msg.Translate(Envs.GetCtx(), "C_BPartner_ID");
            nameQLabel.Text = Msg.Translate(Envs.GetCtx(), "Name");
            descriptionQLabel.Text = Msg.Translate(Envs.GetCtx(), "Description");
            helpQLabel.Text = Msg.Translate(Envs.GetCtx(), "Help");
            createdByQLabel.Text = Msg.Translate(Envs.GetCtx(), "CreatedBy");
            createdQLabel.Text = Msg.Translate(Envs.GetCtx(), "Created");

            createdByLabel.Text = Msg.Translate(Envs.GetCtx(), "CreatedBy");
            createdLabel.Text = Msg.Translate(Envs.GetCtx(), "Created");
            nameLabel.Text = Msg.Translate(Envs.GetCtx(), "Name");
            descriptionLabel.Text = Msg.Translate(Envs.GetCtx(), "Description");
            helpLabel.Text = Msg.Translate(Envs.GetCtx(), "Help");
            tabItem1.Header = Msg.Translate(Envs.GetCtx(), "Query");
            tabItem2.Header = Msg.Translate(Envs.GetCtx(), "View");
        }


        public void Dispose()
        {
            if (m_frame != null)
            {
                m_frame.Dispose();
            }
            m_frame = null;
        }


        private void UpdateQDisplay()
        {
            bool reports = (bool)reportField.IsChecked;
            log.Config("Reports=" + reports);
            //	Show

            if (reports)
            {
                grid1.RowDefinitions[2].Height = new GridLength(35, GridUnitType.Pixel);
                grid1.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Pixel);

                processLabel.Visibility = System.Windows.Visibility.Visible;
                processField.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                grid1.RowDefinitions[1].Height = new GridLength(35, GridUnitType.Pixel);
                grid1.RowDefinitions[2].Height = new GridLength(0, GridUnitType.Pixel);

                processLabel.Visibility = System.Windows.Visibility.Collapsed;
                processField.Visibility = System.Windows.Visibility.Collapsed;
            }

            //	Hide
            if (reports)
            {
                bPartnerLabel.Visibility = System.Windows.Visibility.Collapsed;
                bPartnerField.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                bPartnerLabel.Visibility = System.Windows.Visibility.Visible;
                bPartnerField.Visibility = System.Windows.Visibility.Visible;

            }
        }


        public void Query(bool isReport, int AD_Table_ID, int Record_ID)
        {
            log.Config("Report=" + isReport + ", AD_Table_ID=" + AD_Table_ID + ",Record_ID=" + Record_ID);
            Deployment.Current.Dispatcher.BeginInvoke(() => reportField.IsChecked = isReport);
            m_AD_Table_ID = AD_Table_ID;
            m_Record_ID = Record_ID;
            Cmd_Query();
        }	//	query	


        private void Cmd_Query()
        {
            PageStatus.IsBusy = true;
            StringBuilder sql = new StringBuilder();
            bool reports = (bool)reportField.IsChecked;

            MRole role = null;
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += (ov, ev) =>
            {
                role = MRole.GetDefault();
            };

            bgw.RunWorkerCompleted += (ov, ev) =>
            {
                try
                {
                    if (!role.IsCanReport())
                    {
                        log.Warning("User/Role cannot Report AD_User_ID=" + Envs.GetCtx().GetAD_User_ID());
                        return;
                    }
                    sql.Append(" AND IsReport=").Append(reports ? "'Y'" : "'N'");

                    //	Process
                    if (reports)
                    {
                        KeyNamePair nn = (KeyNamePair)processField.SelectedItem;
                        if (nn != null && nn.GetKey() > 0)
                            sql.Append(" AND AD_Process_ID=").Append(nn.GetKey());
                    }

                    //	Table
                    if (m_AD_Table_ID > 0)
                    {
                        sql.Append(" AND ((AD_Table_ID=").Append(m_AD_Table_ID);
                        if (m_Record_ID > 0)
                            sql.Append(" AND Record_ID=").Append(m_Record_ID);
                        sql.Append(")");
                        if (m_AD_Table_ID == X_C_BPartner.Table_ID && m_Record_ID > 0)
                            sql.Append(" OR C_BPartner_ID=").Append(m_Record_ID);
                        sql.Append(")");
                        //	Reset for query
                        m_AD_Table_ID = 0;
                        m_Record_ID = 0;
                    }
                    else
                    {
                        KeyNamePair nn = (KeyNamePair)tableField.SelectedItem;
                        if (nn != null && nn.GetKey() > 0)
                            sql.Append(" AND AD_Table_ID=").Append(nn.GetKey());
                    }

                    //	Business Partner
                    if (!reports)
                    {
                        Object ii = bPartnerField.GetValue();
                        if (ii != null)
                            sql.Append(" AND C_BPartner_ID=").Append((int)ii);
                        else
                            sql.Append(" AND C_BPartner_ID IS NOT NULL");
                    }

                    //	Name
                    String ss = nameQField.Text;
                    if (ss != null && ss.Length > 0)
                    {
                        if (ss.IndexOf("%") != -1 || ss.IndexOf("_") != -1)
                            sql.Append(" AND Name LIKE ").Append(DB.TO_STRING(ss));
                        else
                            sql.Append(" AND Name=").Append(DB.TO_STRING(ss));
                    }

                    //	Description
                    ss = descriptionQField.Text;
                    if (ss != null && ss.Length > 0)
                    {
                        if (ss.IndexOf("%") != -1 || ss.IndexOf("_") != -1)
                            sql.Append(" AND Description LIKE ").Append(DB.TO_STRING(ss));
                        else
                            sql.Append(" AND Description=").Append(DB.TO_STRING(ss));
                    }

                    //	Help
                    ss = helpQField.Text;
                    if (ss != null && ss.Length > 0)
                    {
                        if (ss.IndexOf("%") != -1 || ss.IndexOf("_") != -1)
                            sql.Append(" AND Help LIKE ").Append(DB.TO_STRING(ss));
                        else
                            sql.Append(" AND Help=").Append(DB.TO_STRING(ss));
                    }

                    //	CreatedBy
                    KeyNamePair nnn = (KeyNamePair)createdByQField.SelectedItem;
                    if (nnn != null && nnn.GetKey() > 0)
                        sql.Append(" AND CreatedBy=").Append(nnn.GetKey());

                    //	Created
                    Object tt = createdQFrom.Text;
                    if (tt != "")
                        sql.Append(" AND Created>=").Append(DB.TO_DATE(Convert.ToDateTime(tt), true));
                    tt = createdQTo.Text;
                    if (tt != "")
                        sql.Append(" AND Created<").Append(DB.TO_DATE(TimeUtil.AddDays(Convert.ToDateTime(tt), 1), true));

                    log.Fine(sql.ToString());

                    //	Process Access
                    sql.Append(" AND (AD_Process_ID IS NULL OR AD_Process_ID IN "
                        + "(SELECT AD_Process_ID FROM AD_Process_Access WHERE AD_Role_ID=")
                        .Append(role.GetAD_Role_ID()).Append("))");
                    //	Table Access
                    sql.Append(" AND (AD_Table_ID IS NULL "
                        + "OR (AD_Table_ID IS NOT NULL AND AD_Process_ID IS NOT NULL) "	//	Menu Reports 
                        + "OR AD_Table_ID IN "
                        + "(SELECT t.AD_Table_ID FROM AD_Tab t"
                        + " INNER JOIN AD_Window_Access wa ON (t.AD_Window_ID=wa.AD_Window_ID) "
                        + "WHERE wa.AD_Role_ID=").Append(role.GetAD_Role_ID()).Append("))");
                    log.Finest(sql.ToString());
                }
                catch
                {
                    ibtnOKS.IsEnabled = true;
                }

                BackgroundWorker bgwInn = new BackgroundWorker();
                bgwInn.DoWork += (ovInn, evInn) =>
                {
                    m_archives = MArchive.Get(Envs.GetCtx(), sql.ToString());
                };

                bgwInn.RunWorkerCompleted += (ovInn, evInn) =>
                {
                    m_index = 1;
                    tabControl1.SelectedIndex = 1;
                    UpdateVDisplay(false);
                    PageStatus.IsBusy = false;
                    log.Info("Length=" + m_archives.Length);
                    ibtnOKS.IsEnabled = true;
                };

                bgwInn.RunWorkerAsync();
            };

            bgw.RunWorkerAsync();
            //




        }	//	cmd_query

        private void UpdateVDisplay(bool next)
        {
            PageStatus.IsBusy = true;
            if (m_archives == null)
                m_archives = new MArchive[0];
            if (next)
                m_index++;
            else
                m_index--;
            if (m_index >= m_archives.Length - 1)
                m_index = m_archives.Length - 1;
            if (m_index < 0)
                m_index = 0;

            bBack.IsEnabled = (m_index > 0);
            bNext.IsEnabled = (m_index < m_archives.Length - 1);
            //ibtnCancelS.Enabled = ;
            //ibtnOKS.Enabled = m_index < m_archives.Length - 1;
            //updateArchive.setEnabled(false);
            //
            log.Info("Index=" + m_index + ", Length=" + m_archives.Length);
            if (m_archives.Length == 0)
            {
                positionInfo.Content = "No Record Found";
                createdByField.Text = "";
                createdField.Text = "";
                nameField.Text = "";
                descriptionField.Text = "";
                //commentField.Text = "";
                if (c1ReportViewer1 != null)
                {
                    c1ReportViewer1.CloseDocument();
                }
                return;
            }
            //
            positionInfo.Content = m_index + 1 + " of " + m_archives.Length;
            MArchive ar = m_archives[m_index];
            createdByField.Text = ar.MCreatedByName;
            createdField.Text = ar.GetCreated().ToString();
            nameField.Text = ar.GetName() == null ? "" : ar.GetName();
            descriptionField.Text = ar.GetDescription() == null ? "" : ar.GetDescription();
            helpField.Text = ar.GetHelp() == null ? "" : ar.GetHelp();
            //
            try
            {
                MemoryStream ms = ar.GetInputStream();
                if (c1ReportViewer1 != null)
                {
                    c1ReportViewer1.LoadDocument(ms);
                }
            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "pdf", e);
                PageStatus.IsBusy = false;
                //pdfViewer.clearDocument();
            }

            PageStatus.IsBusy = false;
        }
        private void reportField_Checked(object sender, RoutedEventArgs e)
        {
            UpdateQDisplay();
        }

        private void reportField_Unchecked(object sender, RoutedEventArgs e)
        {
            UpdateQDisplay();
        }

        private void ibtnOKS_Click(object sender, RoutedEventArgs e)
        {
            ibtnOKS.IsEnabled = false;
            if (tabControl1.SelectedIndex == 0)
            {
                Cmd_Query();
            }
            else
            {
                m_frame.Close();
            }
        }

        private void bBack_Click(object sender, RoutedEventArgs e)
        {
            UpdateVDisplay(false);
        }

        private void bNext_Click(object sender, RoutedEventArgs e)
        {
            UpdateVDisplay(true);
        }	//	updateQDisplay

        private bool IsSame(String s1, String s2)
        {
            if (s1 == null)
                return s2 == null;
            else if (s2 == null)
                return false;
            else
                return s1.Equals(s2);
        }	//	isSame

        private void Cmd_UpdateArchive()
        {
            PageStatus.IsBusy = true;
            string sNameField = nameField.Text;
            string sDescriptionField = descriptionField.Text;
            string sHelpField = helpField.Text;
            BackgroundWorker bgw = new BackgroundWorker();
            bgw.DoWork += (ov, ev) =>
            {
                MArchive ar = m_archives[m_index];
                bool update = false;
                if (!IsSame(sNameField, ar.GetName()))
                {
                    String newText = sNameField;
                    if (newText != null && newText.Length > 0)
                    {
                        ar.SetName(newText);
                        update = true;
                    }
                }
                if (!IsSame(sDescriptionField, ar.GetDescription()))
                {
                    ar.SetDescription(sDescriptionField);
                    update = true;
                }
                if (!IsSame(sHelpField, ar.GetHelp()))
                {
                    ar.SetHelp(sHelpField);
                    update = true;
                }
                log.Info("Update=" + update);
                if (update)
                    ar.Save();
            };

            bgw.RunWorkerCompleted += (ov, ev) =>
            {
                m_index++;
                UpdateVDisplay(false);
                PageStatus.IsBusy = false;
            };

            bgw.RunWorkerAsync();


            //

        }

        private void bUpdateArchive_Click(object sender, RoutedEventArgs e)
        {
            Cmd_UpdateArchive();
        }	//	cmd_updateArchive


        public void SetTableID(bool p, int AD_Table_ID, int Record_ID)
        {
            m_AD_Table_ID = AD_Table_ID;
        }
    }
}
